﻿using System;

namespace Sencha.Serialization.Exceptions
{
	[Serializable]
	public class JsonSerializationException : System.Runtime.Serialization.SerializationException
	{
		public int Code { get; set; }
		public int LineNumber { get; set; }
		public int ColumnNumber { get; set; }
		public long CharactersReaded { get; set; }
		public long CharactersWritten { get; set; }

		internal JsonSerializationException(string message, ErrorCode errorCode, IJsonReader reader)
			: base(message)
		{
			this.Code = (int)errorCode;
			if (reader != null)
				this.Update(reader);
		}
		internal JsonSerializationException(string message, ErrorCode errorCode, IJsonWriter writer)
			: base(message)
		{
			this.Code = (int)errorCode;
			if (writer != null)
				this.Update(writer);
		}
		internal JsonSerializationException(string message, ErrorCode errorCode)
			: base(message)
		{
			this.Code = (int)errorCode;
		}
		internal JsonSerializationException(string message, ErrorCode errorCode, IJsonReader reader, Exception innerException)
			: base(message, innerException)
		{
			this.Code = (int)errorCode;
			if (reader != null)
				this.Update(reader);
		}
		internal JsonSerializationException(string message, ErrorCode errorCode, IJsonWriter writer, Exception innerException)
			: base(message, innerException)
		{
			this.Code = (int)errorCode;
			if (writer != null)
				this.Update(writer);
		}
		internal JsonSerializationException(string message, ErrorCode errorCode, Exception innerException)
			: base(message, innerException)
		{
			this.Code = (int)errorCode;
		}
		internal JsonSerializationException(string message, Exception innerException)
			: base(message, innerException)
		{
			this.Code = (int)ErrorCode.GenericJsonSerializationException;
		}
		internal JsonSerializationException(string message)
			: base(message)
		{
			this.Code = (int)ErrorCode.GenericJsonSerializationException;
		}
		internal JsonSerializationException()
			: base(Loc.GetErrorString("Exception_JsonSerializationException"))
		{
			this.Code = (int)ErrorCode.GenericJsonSerializationException;
		}
		internal JsonSerializationException(Exception innerException)
			: base(Loc.GetErrorString("Exception_JsonSerializationException"), innerException)
		{
			this.Code = (int)ErrorCode.GenericJsonSerializationException;
		}

		protected JsonSerializationException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
			: base(info, context)
		{
			this.Code = info.GetInt32("Code");
			this.LineNumber = info.GetInt32("LineNumber");
			this.ColumnNumber = info.GetInt32("ColumnNumber");
			this.CharactersReaded = info.GetInt64("CharactersReaded");
			this.CharactersWritten = info.GetInt64("CharactersWritten");
		}

		private void Update(IJsonReader reader)
		{
			if (reader == null)
				throw new ArgumentNullException("reader");
			System.Diagnostics.Contracts.Contract.EndContractBlock();

			this.LineNumber = reader.Value.LineNumber;
			this.ColumnNumber = reader.Value.ColumnNumber;
			this.CharactersReaded = reader.CharactersReaded;
		}
		private void Update(IJsonWriter writer)
		{
			if (writer == null)
				throw new ArgumentNullException("writer");
			System.Diagnostics.Contracts.Contract.EndContractBlock();

			this.CharactersWritten = writer.CharactersWritten;
		}

		[System.Security.SecurityCritical]
		public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
		{
			info.AddValue("Code", this.Code);
			info.AddValue("LineNumber", this.LineNumber);
			info.AddValue("ColumnNumber", this.ColumnNumber);
			info.AddValue("CharactersReaded", this.CharactersReaded);
			info.AddValue("CharactersWritten", this.CharactersWritten);

			base.GetObjectData(info, context);
		}
	}
}
